package com.example.app.util

import android.annotation.SuppressLint
import android.app.Notification
import android.app.NotificationChannel
import android.app.NotificationManager
import android.content.Context
import android.content.Intent
import android.database.Cursor
import android.media.MediaPlayer
import android.net.Uri
import android.os.Build
import android.os.VibrationEffect
import android.os.Vibrator
import android.provider.OpenableColumns
import android.provider.Settings
import android.util.TypedValue
import android.view.ViewTreeObserver
import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.Composable
import androidx.compose.runtime.DisposableEffect
import androidx.compose.runtime.MutableState
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.drawBehind
import androidx.compose.ui.focus.FocusManager
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalView
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import androidx.core.app.NotificationCompat
import androidx.core.view.ViewCompat
import androidx.core.view.WindowInsetsCompat
import com.example.app.R
import com.example.app.data.enum.BorderState
import java.time.Instant
import java.time.LocalDateTime
import java.time.ZoneId
import java.time.ZoneOffset
import java.time.format.DateTimeFormatter
import java.util.Locale




//震动
fun performVibration(repeat: Int, context: Context): Vibrator? {
    val vibrator = context.getSystemService(Context.VIBRATOR_SERVICE) as Vibrator
    // 定义震动模式，例如：震动1秒，停止1秒，再震动1秒
    val pattern = longArrayOf(0, 1000, 1000)
    // 判断设备是否支持震动
    if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O && vibrator.hasVibrator()) {
        // 参数1：定义震动模式，参数2：-1 表示不重复，非 -1 表示从 pattern 数组的指定索引开始循环
        vibrator.vibrate(VibrationEffect.createWaveform(pattern, repeat))
    } else if (vibrator.hasVibrator()) {
        // 兼容低版本 Android 设备的震动方式
        vibrator.vibrate(pattern, repeat)
    }
    return vibrator
}
//铃声
fun playAlarmSound(context: Context): MediaPlayer? {
    // 播放铃声
    val mediaPlayer = MediaPlayer.create(context, Settings.System.DEFAULT_ALARM_ALERT_URI)
    mediaPlayer.isLooping = true
    mediaPlayer.start()
    return mediaPlayer
}
//通知栏显示待办 需要开启 POST_NOTIFICATIONS 权限
fun showNotificationWithBadge(
    Message: String?,
    Title: String?,
    channelId: String = "111",
    channelName: String = "222",
    context: Context,
    smallIcon: Int = R.drawable.bg
): Notification {
    val notificationBuilder = NotificationCompat.Builder(context, channelId)
        .setContentTitle(Title)
        .setContentText(Message)
        .setSmallIcon(smallIcon)
        .setPriority(NotificationCompat.PRIORITY_DEFAULT)

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        var notificationManager =
            context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
        val channel =
            NotificationChannel(channelId, channelName, NotificationManager.IMPORTANCE_DEFAULT)
        notificationManager?.createNotificationChannel(channel)
    }

    return notificationBuilder.build()
}
//没权限 , 跳转到设置页面去设置
fun openAppSettings(context: Context) {
    //默认的权限
    val intent = Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS)
    //闹钟的权限
    //val intent = Intent(Settings.ACTION_REQUEST_SCHEDULE_EXACT_ALARM)
    val uri: Uri = Uri.fromParts("package", context.packageName, null)
    intent.data = uri
    context.startActivity(intent)
}
//时间戳获取周几
fun getDayName(timestamp: Long): String {
    //Instant.ofEpochMilli(item.CreateAt.toLong()).atZone(ZoneOffset.ofHours(8)).toLocalDate().dayOfWeek
    var nameDay = arrayListOf<String>(
        "周一",
        "周二",
        "周三",
        "周四",
        "周五",
        "周六",
        "周日",
    )

    return nameDay.get(
        Instant.ofEpochMilli(timestamp)
            .atZone(ZoneOffset.ofHours(8))
            .toLocalDate().dayOfWeek.value - 1
    )
}
@Composable
fun checkKeyBoardState(focusManger: FocusManager): MutableState<Boolean> {
    //判断 键盘是否打开
    //https://stackoverflow.com/questions/68847559/how-can-i-detect-keyboard-opening-and-closing-in-jetpack-compose
    val view = LocalView.current
    val viewTreeObserver = view.viewTreeObserver
    var state = remember {
        mutableStateOf(false)
    }
    DisposableEffect(viewTreeObserver) {
        val listener = ViewTreeObserver.OnGlobalLayoutListener {
            val isKeyboardOpen = ViewCompat.getRootWindowInsets(view)
                                     ?.isVisible(WindowInsetsCompat.Type.ime()) ?: true
            state.value = isKeyboardOpen
        }

        viewTreeObserver.addOnGlobalLayoutListener(listener)
        onDispose {
            viewTreeObserver.removeOnGlobalLayoutListener(listener)
        }
    }
    return state
}

data class MyBorderConfig(
    var borderColor: Color = Color.Black.copy(alpha = .08f),
    var strokeWidth: Dp? = 1.dp,
    var position: BorderState? = BorderState.BORDER_LEFT
)
@Composable
fun Modifier.myBorder(
    myBorderConfig: MyBorderConfig = MyBorderConfig(borderColor = MaterialTheme.colorScheme.onBackground)
): Modifier {
    return this.drawBehind {
        var startX = 0f
        when (myBorderConfig.position!!) {
            BorderState.BORDER_LEFT -> {
                startX = 0f
            }

            BorderState.BORDER_TOP -> {
                startX = 0f
            }

            BorderState.BORDER_BOTTOM -> {
                startX = 0f
            }

            BorderState.BORDER_RIGHT -> {
                startX = size.width
            }

            else -> {
            }
        }
        var startY = 0f
        when (myBorderConfig.position!!) {
            BorderState.BORDER_LEFT -> {
                startY = 0f
            }

            BorderState.BORDER_TOP -> {
                startY = 0f
            }

            BorderState.BORDER_BOTTOM -> {
                startY = size.height
            }

            BorderState.BORDER_RIGHT -> {
                startY = 0f
            }

            else -> {
            }
        }
        var endX = 0f
        when (myBorderConfig.position!!) {
            BorderState.BORDER_LEFT -> {
                endX = 0f
            }

            BorderState.BORDER_TOP -> {
                endX = size.width
            }

            BorderState.BORDER_BOTTOM -> {
                endX = size.width
            }

            BorderState.BORDER_RIGHT -> {
                endX = size.width
            }

            else -> {
            }
        }
        var endY = 0f
        when (myBorderConfig.position!!) {
            BorderState.BORDER_LEFT -> {
                endY = size.height
            }

            BorderState.BORDER_TOP -> {
                endY = 0f
            }

            BorderState.BORDER_BOTTOM -> {
                endY = size.height
            }

            BorderState.BORDER_RIGHT -> {
                endY = size.height
            }

            else -> {
            }
        }

        drawLine(
            color = myBorderConfig.borderColor!!,
            strokeWidth = myBorderConfig.strokeWidth!!.toPx(),
            start = Offset(
                startX,
                startY
            ),
            end = Offset(
                endX,
                endY
            )
        )
    }
}
//转成月日
fun converToMonthDay(dateTime: LocalDateTime): String {
    return dateTime.monthValue.toString() + " / " + dateTime.dayOfMonth
}
@SuppressLint("Range")
fun getFileName(uri: Uri, context: Context): String? {
    var result: String? = null
    if (uri.scheme.equals("content")) {
        val cursor: Cursor? = context.contentResolver.query(uri, null, null, null, null)
        try {
            if (cursor != null && cursor.moveToFirst()) {
                result = cursor.getString(cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME))
            }
        } finally {
            cursor!!.close()
        }
    }
    if (result == null) {
        result = uri.path
        val cut = result!!.lastIndexOf('/')
        if (cut != -1) {
            result = result.substring(cut + 1)
        }
    }
    return result
}

fun myLog(msg: Any, tag: String? = msg.toString()) {
    println("${tag}----->${msg}")
}
//px转sp
fun Context.pxToSp(px: Float = 12f): Float {
    // 获取DisplayMetrics对象
    val metrics = resources.displayMetrics
    // 使用TypedValue进行转换
    val spValue = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_PX, px, metrics)
    // 返回转换后的sp值
    return spValue
}
//px转dp
fun Context.pxToDp(px: Float = 12f): Float {
    // 获取DisplayMetrics对象
    val metrics = resources.displayMetrics
    // 使用公式进行转换
    val dp = px / (metrics.densityDpi / 160f)
    // 返回转换后的dp值
    return dp
}
/*fun Context.dpToPx(dp: Float): Int {
    // 获取DisplayMetrics对象
    val metrics = resources.displayMetrics
    // 使用公式进行转换
    val px = (dp * metrics.density).toInt()
    // 返回转换后的px值
    return px
}*/
fun Context.dpToPx(dp: Dp): Int {
    return TypedValue.applyDimension(
        TypedValue.COMPLEX_UNIT_DIP,
        dp.value,
        resources.displayMetrics
    ).toInt()
}

fun Context.spToPx(sp: Float): Int {
    // 获取DisplayMetrics对象
    val metrics = resources.displayMetrics
    // 使用公式进行转换
    val px = (sp * metrics.scaledDensity).toInt()
    // 返回转换后的px值
    return px
}
//dateString "2022-10-03"
fun dateStrToDateLong(dateString: String): Long {
    val localDateTime = LocalDateTime.parse(dateString + "T00:00:00") // 假定时间为当天0点
    val zonedDateTime = localDateTime.atZone(ZoneId.systemDefault()) // 转换为系统默认时区的 ZonedDateTime
    return zonedDateTime.toInstant().toEpochMilli()
}
//时间戳字符串 格式化成 2024/5/29
fun formatTimestamp(timestamp: Long, pattern: String = "yyyy/MM/dd"): String {
    // 将时间戳转换为Instant对象
    val instant = Instant.ofEpochMilli(timestamp)
    // 将Instant转换为LocalDateTime对象，并指定时区（这里使用东八区，即北京时间）
    val localDateTime = LocalDateTime.ofInstant(instant, ZoneId.of("Asia/Shanghai"))
    // 创建日期时间格式化器
    val formatter = DateTimeFormatter.ofPattern(pattern)
    // 使用格式化器格式化日期时间
    return localDateTime.format(formatter)
}
//返回日期和星期几
fun formatTimestampToChineseWeekday(
    timestamp: Long,
    pattern: String = "yyyy/MM/dd"
): Pair<String, String> {
    // 将时间戳转换为Instant对象
    val instant = Instant.ofEpochMilli(timestamp)
    // 将Instant转换为LocalDateTime对象，并指定时区（这里使用东八区，即北京时间）
    val localDateTime = LocalDateTime.ofInstant(instant, ZoneId.of("Asia/Shanghai"))
    // 创建日期时间格式化器，包含中文星期几
    // 注意：样式 'E' 代表星期几的简称，样式 'EEEE' 代表星期几的全称
    var formatter = DateTimeFormatter.ofPattern(pattern, Locale.getDefault()) // 使用默认语言环境的格式
    formatter = formatter.withLocale(Locale.CHINA) // 切换到中文环境
    val weekdayFormatter = DateTimeFormatter.ofPattern("EEEE", Locale.CHINA) // 中文星期几的全称
    // 使用格式化器格式化日期时间
    val formattedDate = localDateTime.format(formatter)
    val formattedWeekday = localDateTime.format(weekdayFormatter)

    return Pair(formattedDate, formattedWeekday)
}
